#define _CRT_SECURE_NO_WARNINGS  1
#include"string.h"

namespace zy
{
	
	void string::swap(string& s)
	{
		std::swap(_capacity, s._capacity);
		std::swap(_size, s._size);
		std::swap(_str, s._str);
	}

	string& string::operator = (const string& s)
	{
		if (s.c_str() != _str)
		{
			string tmp(s.c_str());
			swap(tmp);
		}
		return *this;
	}

	void string::reserve(int n)
	{
		//if (_capacity < n)
		//{
		//	char* str = new char[_capacity = _capacity ? 2 * _capacity : 4];
		//	strcpy(str, _str);
		//	std::swap(str, _str);
		//	delete[] str;
		//}

		if(_capacity < n)
		{
			char* str = new char[n+1];
			strcpy(str,_str);
			delete[]_str;
			_str = str;
			_capacity = n;
		}

	}

	string& string::operator +=(const string& s)
	{
		int len = strlen(s.c_str());
		if(len+_size>_capacity)
		{
			reserve(_capacity ? 2 * _capacity : 4);
		}
		strcpy(_str + _size, s.c_str());
		_size = len + _size;
		return *this;
	}
	string& string::operator +=(const char* str)
	{
		int len = strlen(str);
		reserve(len + _size);
		strcpy(_str + _size, str);
		_size = len + _size;
		return *this;

	}

	char string::operator[](int pos)
	{
		assert(pos > -1 && pos < _size);
		return _str[pos];
	}

	char string::operator[](int pos)const
	{
		assert(pos > -1 && pos < _size);
		return _str[pos];
	}

	bool string::operator >(const string& s1)const
	{
		return strcmp(_str, s1.c_str()) > 0;
	}
	bool string::operator ==(const string& s1)const
	{
		return strcmp(_str, s1.c_str())==0;
	}
	bool string::operator >=(const string& s1)const
	{
		return *this > s1 || *this == s1;
	}
	bool string::operator <(const string& s1)const
	{
		return !(*this >= s1);
	}
	bool string::operator <=(const string& s1)const
	{
		return !(*this > s1);
	}
	bool string::operator !=(const string& s1)const
	{
		return !(*this == s1);
	}


	string& string::erase(size_t pos, size_t len)
	{
		assert(pos < _size);
		if (len + pos >= _size)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			int end = pos;
			while (end < _size+1-len)
			{
				_str[end] = _str[end+len];
				end++;
			}
			_size = _size - len;
		}
		return *this;
	}
	string& string::insert(size_t pos, const string& str)
	{
		assert(pos < _size);
		int len = strlen(str.c_str());
		if (len + _size >= _size)
		{
			reserve(len+_size+1);
		}
		
		int end = _size + len;
		while (end > (int)(pos + len - 1))
		{
			_str[end] = _str[end - len];
			end--;
		}

		memmove(_str + pos, str.c_str(),len);
		_size = _size + len;
		return *this;
	}
	string& string::insert(size_t pos, const char s)
	{
		assert(pos < _size);
		reserve(_size + 1);
		int end = _size + 1;
		while (end>pos)
		{
			_str[end] = _str[end - 1];
			end--;
		}
		_str[pos] = s;
		_size++;

		return *this;

	}
	string& string::append(const string& str)
	{
		return insert(_size - 1, str);
	}
	string  string::substr(size_t pos , size_t len ) const
	{
		assert(pos < _size);
		if (len + pos > _size||len==-1)
			len = _size - pos;
		char* str = new char[len+1];
		str[len] = '\0';
		strncpy(str, _str + pos, len);
		string s(str);
		delete[]str;
		return s;
	}



	istream& operator >>(istream& in, string& s1)
	{

		s1.clear();

		const int N = 256;
		char buff[N];
		char ch = in.get();
		int i = 0;
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == 255)
			{
				buff[i] = '\0';
				s1 += buff;
				i = 0;
			}

			ch = in.get();
		}

		if (i != 0)
		{
			buff[i] = '\0';
			s1 += buff;
		}

		return in;
	}
	ostream& operator<<(ostream& out, const string& s)
	{
		out << s.c_str();
		return out;
	}
}